﻿using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using personalplaner.common.controls.documents;

namespace personalplaner.common.controls
{
	[TemplatePart(Name = "PART_PreviousButton", Type = typeof (Button))]
	[TemplatePart(Name = "PART_NextButton", Type = typeof (Button))]
	[TemplatePart(Name = "PART_SelectedContentHost", Type = typeof (ContentPresenter))]
	[StyleTypedProperty(Property = "ItemContainerStyle", StyleTargetType = typeof (PrintPreviewItem))]
	public class PrintPreviewItemsControl : Selector, INotifyPropertyChanged
	{
		#region INotifyPropertyChanged Members

		public event PropertyChangedEventHandler PropertyChanged; // = delegate { };

		protected void RaisePropertyChanged(string propertyName)
		{
			if (PropertyChanged != null)
				PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
		}

		#endregion

		private Button _nextButton;
		private Button _previousButton;

		static PrintPreviewItemsControl()
		{
			DefaultStyleKeyProperty.OverrideMetadata(typeof (PrintPreviewItemsControl),
			                                         new FrameworkPropertyMetadata(typeof (PrintPreviewItemsControl)));
		}

		public PrintPreviewItemsControl()
		{
			//TabControl
			Loaded += new RoutedEventHandler(OnLoaded);
		}
        
		#region Overrides
        
		public override void OnApplyTemplate()
		{
			if (_nextButton != null)
				_nextButton.Click -= new RoutedEventHandler(NextButtonClick);

			if (_previousButton != null)
				_previousButton.Click -= new RoutedEventHandler(PreviousButtoClick);

			base.OnApplyTemplate();

			_nextButton = GetTemplateChild("PART_NextButton") as Button;
			if (_nextButton != null)
				_nextButton.Click += new RoutedEventHandler(NextButtonClick);

			_previousButton = GetTemplateChild("PART_PreviousButton") as Button;
			if (_previousButton != null)
				_previousButton.Click += new RoutedEventHandler(PreviousButtoClick);
		}

		protected override void OnItemsSourceChanged(System.Collections.IEnumerable oldValue,
		                                             System.Collections.IEnumerable newValue)
		{
			base.OnItemsSourceChanged(oldValue, newValue);

			if (Items != null && Items.Count > 0 && SelectedIndex < 0)
				SelectedIndex = 0;
		}

		protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
		{
			base.OnItemsChanged(e);

			if (Items != null && Items.Count > 0 && SelectedIndex < 0)
				SelectedIndex = 0;
		}

		protected override void OnSelectionChanged(SelectionChangedEventArgs e)
		{
			base.OnSelectionChanged(e);

			RaisePropertyChanged("SelectedPageNumber");

			EnableButtons();

			for (int i = 0; i < Items.Count; i++)
			{
				var tmp = GetSelectedPageItem(i);
				if (tmp != null)
				{
					tmp.Unfocus();
				}
			}

			PrintPreviewItem item = GetSelectedPageItem(SelectedIndex);
			if (item != null)
			{
				item.SetFocus();
			}
		}

		private PrintPreviewItem GetSelectedPageItem(int SelectedIndex)
		{
			object selectedItem = SelectedItem;
			if (selectedItem != null)
			{
				// Check if the selected item is a PrintPreviewItem 
				var page = selectedItem as PrintPreviewItem;
				if (page == null)
				{
					// It is a data item, get its TabItem container
					page = ItemContainerGenerator.ContainerFromIndex(SelectedIndex) as PrintPreviewItem;

					// Due to event leapfrogging, we may have the wrong container. 
					// If so, re-fetch the right container using a more expensive method.
					// (BTW, the previous line will cause a debug assert in this case)  [Dev10 452711] 
					if (page != null &&
					    !Object.Equals(selectedItem, ItemContainerGenerator.ItemFromContainer(page)))
					{
						page = ItemContainerGenerator.ContainerFromItem(selectedItem) as PrintPreviewItem;
					}
				}

				return page;
			}

			return null;
		}

		/// <summary> 
		/// Return true if the item is (or is eligible to be) its own ItemUI
		/// </summary> 
		protected override bool IsItemItsOwnContainerOverride(object item)
		{
			return (item is PrintPreviewItem);
		}

		/// <summary> 
		/// Create or identify the element used to display the given item. 
		/// </summary> 
		protected override DependencyObject GetContainerForItemOverride()
		{
			return new PrintPreviewItem();
		}

		/// <summary>
		/// Prepares the specified element to display the specified item.
		/// </summary>
		/// <param name="element">The element used to display the specified item.</param>
		/// <param name="item">The item to display.</param>
		protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
		{
			// Add the container to the item containers collection
			var itemContainer = (PrintPreviewItem) element;

			if (this.ItemTemplate != null)
			{
				var contentElement = this.ItemTemplate.LoadContent();
				itemContainer.DataContext = item;
				itemContainer.Content = contentElement;
			}
			else
			{
				itemContainer.Content = item;
			}
		}

		#endregion

		#region Helpers methods

		#region Events

		private void OnLoaded(object sender, RoutedEventArgs e)
		{
			EnableButtons();
		}

		private void PreviousButtoClick(object sender, RoutedEventArgs e)
		{
			SelectPreviousPage();
		}

		private void NextButtonClick(object sender, RoutedEventArgs e)
		{
			SelectNextPage();
		}

		#endregion

        //public void RefreshLayout()
        //{
        //    int count = this.VisualChildrenCount;

        //    if (count > 0)
        //    {
        //        UIElement child = GetVisualChild(0) as UIElement;
        //        if (child != null)
        //        {
        //            //var grid = child.Content as PlanGrid

        //            child.UpdateLayout();

        //            //Helper.SetMeasureDataOnChild(this, child, constraint);  // pass along MeasureData so it continues down the tree.
        //            //child.Measure(constraint);
        //            //return child.DesiredSize;
        //        }
        //    }
        //}

		public bool SelectPreviousPage()
		{
			if (SelectedIndex > 0)
			{
				SelectedIndex--;
				return true;
			}

			return false;
		}

		public bool SelectNextPage()
		{
			if (SelectedIndex < Items.Count - 1)
			{
				SelectedIndex++;
				return true;
			}

			return false;
		}

		private void EnableButtons()
		{
			if (_previousButton != null)
			{
				_previousButton.IsEnabled = SelectedIndex > 0;
			}

			if (_nextButton != null && Items != null)
			{
				_nextButton.IsEnabled = SelectedIndex < Items.Count - 1;
			}
		}

		/// <summary>
		/// selects the page with the given page/item index
		/// </summary>
		/// <param name="pageindex"></param>
		public bool SelectPage(int pageindex)
		{
			if (Items == null || pageindex < 0 || pageindex > Items.Count-1)
				return false;

			SelectedIndex = pageindex;
			return true;
		}

		public System.Windows.Documents.DocumentPaginator GetDocumentPaginator()
		{
			return new PrintDocumentPaginator(this);
		}

		#endregion

		#region Properties

		public int SelectedPageNumber
		{
			get
			{
				return SelectedIndex + 1;
			}
			set
			{
				if (Items != null && value >= 0 && value <= Items.Count)
					SelectedIndex = value - 1;

				RaisePropertyChanged("SelectedPageNumber");
			}
		}

		public ContentPresenter SelectedContentPresenter
		{
			get
			{
				return GetTemplateChild("PART_SelectedContentHost") as ContentPresenter;
			}
		}

		#endregion
	}
}
